package cn.yj.cgs.dba.service;

import cn.yj.cgs.dba.entity.Integral;
import cn.yj.cgs.dba.entity.IntegralWater;
import cn.yj.cgs.dba.mapper.IntegralMapper;
import cn.yj.cgs.dba.mapper.IntegralWaterMapper;
import cn.yj.common.Enums;
import cn.yj.common.UUIdUtils;
import cn.yj.commons.utils.BigDecimalUtils;
import cn.yj.params.check.annotation.Require;
import cn.yj.tools.exception.ServiceException;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;

import static cn.yj.commons.utils.FilterNull.isNull;

/**
 * @author 永健
 * @since 2021-10-20 17:34
 */
@Component
public class IntegralCommonService {
    @Resource
    private IntegralWaterMapper waterMapper;

    @Resource
    private IntegralMapper integralMapper;

    /**
     *
     * @param userCode 用户编码
     * @param amount 积分
     * @param isAdd 加还是减
     * @param source 积分来源
     * @param inviteCode 邀请码  source为邀请用户需要
     * @param moneyOne 一个积分得到多少元 source 为提现需要
     * @return
     */
    @Transactional
    public boolean updateIntegral(
            @Require String userCode, @Require BigDecimal amount, boolean isAdd,
            @Require Enums.IntegralWater.SOURCE source, String inviteCode,BigDecimal moneyOne) {
        Integral integral = integralMapper.selectIntegralByUserCodeForUpdate(userCode);
        isNull(integral, String.format("用户积分账户不存在:%s", userCode));

        // 不可小于0
        if (BigDecimalUtils.isLeftLERight(amount, BigDecimal.ZERO)) {
            throw new ServiceException(String.format("积分不可小于或等于0:%s", integral));
        }
        handlerSub(integral, amount, isAdd);
        handlerAdd(integral, amount, isAdd);

        // 流水记录
        IntegralWater integralWater = new IntegralWater();
        integralWater.setUserCode(userCode);
        integralWater.setIntegral(amount);
        integralWater.setType(isAdd? Enums.IntegralWater.TYPE.IN : Enums.IntegralWater.TYPE.OUT);
        integralWater.setOrderNo(UUIdUtils.getUUId32());
        integralWater.setPayAmount(source == Enums.IntegralWater.SOURCE.CASH_OUT? BigDecimalUtils.mul(amount,
                moneyOne) : amount);
        integralWater.setSource(source);
        integralWater.setInviteCode(inviteCode);
        integralWater.setStatus(isAdd? Enums.IntegralWater.STATUS.success :
                Enums.IntegralWater.SOURCE.CASH_OUT == source? Enums.IntegralWater.STATUS.doing :
                        Enums.IntegralWater.STATUS.success);

        // 更新积分
        if (integralMapper.updateById(integral) <= Enums.Common.ZERO) {
            throw new ServiceException("更新积分失败，请稍后重试");
        }
        return waterMapper.insert(integralWater) > Enums.Common.ZERO;
    }

    private void handlerAdd(Integral integral, BigDecimal amount, boolean isAdd) {
        if (isAdd) {
            integral.setIntegral(BigDecimalUtils.add(integral.getIntegral(), amount));
        }
    }

    private void handlerSub(Integral integral, BigDecimal amount, boolean isAdd) {
        if (!isAdd) {
            if (BigDecimalUtils.isLeftLTRight(integral.getIntegral(), amount)) {
                throw new ServiceException(String.format("积分不足:当前积分:%s,使用积分:%s", integral.getIntegral(), amount));
            }
            integral.setIntegral(BigDecimalUtils.sub(integral.getIntegral(), amount));
        }
    }
}
